#ifndef URLNODE_H
#define URLNODE_H
#include <QString>
#include <QRegExp>
#include <QStringList>
#include <QVariant>
#include "sh_global.h"

/**
 * @brief The UrlNode class
 * Works with url nodes
 */
class SHSHARED_EXPORT UrlNode
{
public:
    /**
     * @brief The NodeType enum
     * Type of node
     * INVALID - after default constructor
     * NAME - node or network search by name
     * // REGEXP - ... by regexp (i think don't needed)
     * GROUP_OR - ... by group1 or group2 or ...
     * GROUP_AND - ... by group1 and group2 and ...
     * ALL - *
     * SKIP - <...> in url, can be used like this home/gw_to_abc/.../[log_writer]/write('log entry')
     */
    enum SelectorType {INVALID, NAME, GROUP_OR, GROUP_AND, ALL, SKIP};
    /**
     * @brief UrlNode construct invalid node
     */
    UrlNode();
    /**
     * @brief UrlNode parses url node description
     * @param urlNode name / ({regexp}) / [group of devices or networks] (? / [g1[g2[g3]]] / [g1][g2][g3]) / ...
     */
    UrlNode(const QString &nodeStr);
    /**
     * @brief UrlNode manually construct UrlNode
     * @param selectorType
     * @param selectorData
     */
    UrlNode(SelectorType selectorType, const QVariant &selectorData);
    /**
     * @brief selectorType
     * @return SelectorType type of this node
     */
    SelectorType selectorType() const;
    /**
     * @brief selectorData
     * @return name, groups, or nothing
     */
    QVariant selectorData() const;
    /**
     * @brief match two UrlNode's
     * @return true if success
     * Further master_t is master.selectorType(), matching_t is matching.selectorType(),
     * ms_data is master.selectorData(), mt_data is matching.selectorData()
     * Nodes mathing if:
     * 1) master_t == matching_t && ms_data == mt_data
     * 2) master_t == GROUP_OR && (matching_t == GROUP_OR || matching_t == GROUP_AND)
     * && if master contains one of matching groups
     * 3) master_t == GROUP_AND && (matching_t == GROUP_OR || matching_t == GROUP_AND)
     * && if matching contains all of master groups
     * 4) if master_t == ALL
     */
    static bool match(const UrlNode &master, const UrlNode &matching);
    /** NEED ???
     * @brief match match UrlNode and matching name and groups, if node is name match name, if node is groups match groups etc
     * @param master
     * @param matchingName
     * @param matchingGroups
     * @return
     */
    static bool match(const UrlNode &master,
                      const QString &matchingName,
                      const QStringList &matchingGroups);
    /**
     * @brief toString
     * @return string like this: <selector type>:selector data
     */
    QString toString() const;
private:
    void parse(const QString &node_str);
    SelectorType m_type;
    QVariant m_data;
};

QDataStream SHSHARED_EXPORT &operator<<(QDataStream &out, const UrlNode &node);
QDataStream SHSHARED_EXPORT &operator>>(QDataStream &in, UrlNode &node);
#endif // URLNODE_H
